package com.cx.mall.demo.config;

import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.messaging.Message;
import org.springframework.mock.web.MockHttpServletRequest;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import java.util.Map;
import java.util.concurrent.TimeUnit;
import java.util.function.Consumer;

@Slf4j
@Configuration
public class HandlerConfig {

    @Autowired
    private RedisTemplate redisTemplate;

    /**
     * 消费testOutput-out-0通道的消息
     * 对应MQController中的/payload接口发送的消息
     */
    @Bean
    public Consumer<Message<String>> testInput() {
        return message -> {
            log.info("consumer testInput消息开始，消息内容: {}", message);
            String payload = message.getPayload();
            Map<String, Object> headers = message.getHeaders();
            
            // 获取消息头中的TAG
            String tag = (String) headers.get("TAG");
            log.info("消息TAG: {}", tag);
            
            // 幂等性处理
            String key = "QUE_" + (String) headers.get("ROCKET_MQ_MESSAGE_ID");
            if(redisTemplate.opsForValue().setIfAbsent(key, "1", 60, TimeUnit.SECONDS)){
                // 初始化请求上下文
                RequestAttributes attributes = new ServletRequestAttributes(new MockHttpServletRequest());
                RequestContextHolder.setRequestAttributes(attributes);
                try {
                    log.info("开始处理消息，payload: {}", payload);
                    
                    // 根据TAG进行不同的处理
                    if("success".equals(tag)) {
                        log.info("处理成功类型的消息: {}", payload);
                        // 这里可以添加具体的业务逻辑
                        processSuccessMessage(payload);
                    } else {
                        log.info("处理其他类型的消息: {}", payload);
                        // 这里可以添加其他类型的处理逻辑
                        processOtherMessage(payload, tag);
                    }
                    
                    log.info("消息处理完成");
                } catch (Exception e) {
                    log.error("处理消息失败", e);
                    throw new RuntimeException(e);
                } finally {
                    // 必须清理上下文
                    RequestContextHolder.resetRequestAttributes();
                }
            } else {
                log.info("消息已处理过，跳过重复处理，key: {}", key);
            }
        };
    }

    /**
     * 消费test3Output-out-0通道的消息
     * 对应MQController中的/unique接口发送的消息
     */
    @Bean
    public Consumer<Message<String>> test3Input() {
        return message -> {
            log.info("consumer test3Input消息开始，消息内容: {}", message);
            String payload = message.getPayload();
            Map<String, Object> headers = message.getHeaders();
            
            // 幂等性处理
            String key = "QUE_" + (String) headers.get("ROCKET_MQ_MESSAGE_ID");
            if(redisTemplate.opsForValue().setIfAbsent(key, "1", 60, TimeUnit.SECONDS)){
                // 初始化请求上下文
                RequestAttributes attributes = new ServletRequestAttributes(new MockHttpServletRequest());
                RequestContextHolder.setRequestAttributes(attributes);
                try {
                    log.info("开始处理唯一消息，payload: {}", payload);
                    
                    // 处理唯一消息的业务逻辑
                    processUniqueMessage(payload);
                    
                    log.info("唯一消息处理完成");
                } catch (Exception e) {
                    log.error("处理唯一消息失败", e);
                    throw new RuntimeException(e);
                } finally {
                    // 必须清理上下文
                    RequestContextHolder.resetRequestAttributes();
                }
            } else {
                log.info("唯一消息已处理过，跳过重复处理，key: {}", key);
            }
        };
    }

    /**
     * 处理成功类型的消息
     */
    private void processSuccessMessage(String payload) {
        log.info("处理成功类型消息的具体业务逻辑: {}", payload);
        // 这里可以添加具体的业务处理逻辑
        // 比如：发送通知、更新状态、记录日志等
    }

    /**
     * 处理其他类型的消息
     */
    private void processOtherMessage(String payload, String tag) {
        log.info("处理其他类型消息的具体业务逻辑，payload: {}, tag: {}", payload, tag);
        // 这里可以添加其他类型的处理逻辑
    }

    /**
     * 处理唯一消息
     */
    private void processUniqueMessage(String payload) {
        log.info("处理唯一消息的具体业务逻辑: {}", payload);
        // 这里可以添加唯一消息的处理逻辑
        // 比如：确保某个操作只执行一次
    }
}
